package com.lanyou.esb.cook.proxy.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import com.lanyou.esb.cook.proxy.dao.impl.BaseDao;
import com.lanyou.esb.cook.proxy.entity.IfAvgResTimes;
import com.lanyou.esb.cook.proxy.redis.CommonUtils;
import com.lanyou.esb.cook.proxy.redis.proxy.impl.IfAvgResTimesJedisProxy;
import com.lanyou.esb.cook.proxy.redis.proxy.impl.IfAvgResTimesKeysJedisProxy;
import com.lanyou.esb.cook.proxy.redis.vo.Group;
import com.lanyou.esb.cook.proxy.redis.vo.Group.Entry;
import com.lanyou.esb.cook.proxy.redis.vo.RedisActionType;
import com.lanyou.esb.cook.proxy.service.GroupService;
import com.lanyou.esb.cook.proxy.service.IfAvgResTimesService;
import com.lanyou.esb.cook.proxy.service.Service;
import com.lanyou.esb.cook.proxy.service.push.Push;

/**
 * 接口平均响应时间
 * 
 * @author Davey.wu
 */
public class IfAvgResTimesServiceImpl implements IfAvgResTimesService,
		Service<IfAvgResTimes>, GroupService<IfAvgResTimes> {
	/** 数据库操作接口 **/
	private BaseDao<IfAvgResTimes> dao;
	/** Redis代理接口 **/
	private IfAvgResTimesJedisProxy jedisProxy;
	/** Redis代理接口 **/
	private IfAvgResTimesKeysJedisProxy jedisProxyKeys;
	/** 消息推送接口 **/
	private Push<IfAvgResTimes> push;

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public void save(final List<IfAvgResTimes> list) throws Exception {
		if (list == null || list.isEmpty()) {
			return;
		}
		try {
			TransactionTemplate tt = new TransactionTemplate(
					this.dao.getTransactionManager());
			tt.execute(new TransactionCallback() {
				public Object doInTransaction(TransactionStatus status) {
					return IfAvgResTimesServiceImpl.this.dao.saveAll(list);
				}
			});
		} catch (Exception e) {
			// 保留失败，将记录添加到推送队列中
			push.putToCollection4DB(list);
		}
	}

	@Override
	public void update(List<IfAvgResTimes> list) throws Exception {
		// 志目前不存在更新业务，所以不提供实现
	}

	@Override
	public Group getGroup(IfAvgResTimes ifAvgResTimes) {
		if (ifAvgResTimes == null) {
			return null;
		}
		// 键
		String key = jedisProxy.getKeyFromObject(ifAvgResTimes);
		boolean exists = false;
		try {
			exists = jedisProxy.exists(key);
		} catch (Exception e) {
			exists = false;
		}
		Group group = new Group();
		// string类型条件集合
		List<Entry> strs = new ArrayList<>(3);

		Entry entry = null;
		// 不存在，加入
		if (!exists) {
			String json = "";
			try {
				json = CommonUtils.toJson(ifAvgResTimes);
			} catch (Exception e) {
				// 不能转换成JSON字符串，抛弃该对象
				return null;
			}
			// 添加区间总响应时间对象
			entry = new Entry();
			entry.setKey(key);
			entry.setValue(json);
			entry.setTimeOut(jedisProxy.getTimeOut());
			entry.setType(RedisActionType.SET);
			strs.add(entry);

			// list类型条件集合
			List<Entry> lists = new ArrayList<>(1);

			// 添加更新键
			entry = new Entry();
			entry.setKey(jedisProxyKeys.getKey());
			entry.setValue(key);
			lists.add(entry);

			group.setLists(lists);
		}
		// 区间总响应时间增加
		entry = new Entry();
		entry.setKey(IfAvgResTimesJedisProxy.getNumKey(key));
		entry.setValue(1 + "");
		entry.setTimeOut(jedisProxy.getTimeOut());
		entry.setType(RedisActionType.INCR_BY_FLOAT);
		strs.add(entry);

		// 区间总响应时间增加
		entry = new Entry();
		entry.setKey(IfAvgResTimesJedisProxy.getTimesKey(key));
		entry.setValue(1 + "");
		entry.setTimeOut(jedisProxy.getTimeOut());
		entry.setType(RedisActionType.INCR_BY);
		strs.add(entry);

		group.setStrs(strs);
		return group;
	}

	/**
	 * 将接口平均响应时间存入Redis
	 *
	 * @param ifAvgResTimes
	 */
	@Override
	public void pushToRedis(IfAvgResTimes ifAvgResTimes) {
		String key = jedisProxy.getKeyFromObject(ifAvgResTimes);
		try {
			boolean exists = jedisProxy.exists(key);
			// 已存在，累加
			if (exists) {
				jedisProxy.setex(key, ifAvgResTimes);
			}
			// 不存在，加入
			else {
				jedisProxyKeys.rpushAsStr(jedisProxyKeys.getKey(), key);
				jedisProxy.setex(key, ifAvgResTimes);
			}
		} catch (Exception e) {
			push.putToCollection4Redis(ifAvgResTimes);
		}

	}

	public IfAvgResTimesJedisProxy getJedisProxy() {
		return jedisProxy;
	}

	public void setJedisProxy(IfAvgResTimesJedisProxy jedisProxy) {
		this.jedisProxy = jedisProxy;
	}

	public IfAvgResTimesKeysJedisProxy getJedisProxyKeys() {
		return jedisProxyKeys;
	}

	public void setJedisProxyKeys(IfAvgResTimesKeysJedisProxy jedisProxyKeys) {
		this.jedisProxyKeys = jedisProxyKeys;
	}

	public BaseDao<IfAvgResTimes> getDao() {
		return dao;
	}

	public void setDao(BaseDao<IfAvgResTimes> dao) {
		this.dao = dao;
	}

	public Push<IfAvgResTimes> getPush() {
		return push;
	}

	public void setPush(Push<IfAvgResTimes> push) {
		this.push = push;
	}

}
